package com.LachesismStorm.lachesism.member.service;

import com.LachesismStorm.lachesism.core.email.EmailUtil;
import com.LachesismStorm.lachesism.member.dto.ConstellationDTO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.LachesismStorm.lachesism.core.common.enums.CommonEnum.DATETIME_FORMATTER;
import static com.LachesismStorm.lachesism.core.common.enums.CommonEnum.DATE_FORMATTER;
import static com.LachesismStorm.lachesism.core.util.LachesismTools.getTime;
import static com.LachesismStorm.lachesism.core.util.LachesismTools.getTomorrowTime;

/**
 * @Author lachesism
 * @Date 2024-12-25 14:31
 **/
@Service
public class SchedulerService {
    @Resource
    private EmailUtil emailUtil;
    @Resource
    private YunOService yunoService;

    // 定时任务调度器
    private final ScheduledExecutorService hourlyScheduler = Executors.newScheduledThreadPool(3);
    private final ScheduledExecutorService dailyScheduler = Executors.newScheduledThreadPool(1);
    private final ScheduledExecutorService constellationScheduler = Executors.newScheduledThreadPool(1);
    private final ScheduledExecutorService addOldCalendarScheduler = Executors.newScheduledThreadPool(1);
    private final ScheduledExecutorService sendLunarEmailDelayScheduler = Executors.newScheduledThreadPool(1);
    private final ScheduledExecutorService sendConstellationEmailDelayScheduler = Executors.newScheduledThreadPool(1);

    // 存储姓名、邮箱和星座的关系
    private final Map<String, Member> emailGroup = new HashMap<>();

    // 初始化邮箱关系（可以通过构造函数或其他方法添加更多数据）
    public SchedulerService() {
        // 初始化一些数据
        emailGroup.put("马来貘老婆", new Member("马来貘老婆", "2595647320@qq.com", "双鱼座", "constellationTemplate/Pisces.html"));
        emailGroup.put("梦瑶", new Member("梦瑶", "2601646293@qq.com", "金牛座", "constellationTemplate/Taurus.html"));
        emailGroup.put("王钰", new Member("王钰", "1315814455@qq.com", "金牛座", "constellationTemplate/Taurus.html"));
//        emailGroup.put("余晓婷", new Member("余晓婷", "1940326976@qq.com", "摩羯座", "constellationTemplate/Scorpio.html"));
//        emailGroup.put("嘉巍", new Member("嘉巍", "1968863352@qq.com", "处女座", "constellationTemplate/virgo.html"));
        emailGroup.put("于姐", new Member("于姐", "429461261@qq.com", "水瓶座", "constellationTemplate/Aquarius.html"));
        emailGroup.put("黄姐", new Member("黄姐", "1365829175@qq.com", "狮子座", "constellationTemplate/Leo.html"));
        emailGroup.put("啊栾", new Member("周虹雨", "842012925@qq.com", "射手座", "constellationTemplate/Sagittarius.html"));
//        emailGroup.put("王钰", new Member("王钰", "1315814455@qq.com", "金牛座", "constellationTemplate/Taurus.html"));
    }

    // 计算初始延迟
    private long calculateInitialDelay(LocalTime now, LocalTime targetTime) {
        long nowSeconds = now.toSecondOfDay();
        long targetSeconds = targetTime.toSecondOfDay();
        // 如果当前时间已经过了目标时间，返回第二天的延迟
        return nowSeconds >= targetSeconds ? 24 * 60 * 60 - (nowSeconds - targetSeconds) : targetSeconds - nowSeconds;
    }

    // 启动定时任务
    public void startScheduledTasks(Runnable autoUpload, Runnable getDailyVideo, Runnable clearTempFiles, Runnable getConstellationList, Runnable addOldCalendar) {
        // 每小时任务（整点执行）
        long hourlyInitialDelay = calculateInitialDelayToNextFullHour(LocalTime.now());  // 计算到下一个整点的初始延迟
        hourlyScheduler.scheduleAtFixedRate(autoUpload, hourlyInitialDelay, 60 * 60, TimeUnit.SECONDS);  // 每小时整点执行
        hourlyScheduler.scheduleAtFixedRate(getDailyVideo, hourlyInitialDelay, 60 * 60, TimeUnit.SECONDS);  // 每小时整点执行
//
//        // 每小时任务
//        long hourlyInitialDelay = calculateInitialDelay(LocalTime.now(), LocalTime.of(3, 1));
//        hourlyScheduler.scheduleAtFixedRate(autoUpload, hourlyInitialDelay, 60 * 60, TimeUnit.SECONDS);
//        hourlyScheduler.scheduleAtFixedRate(getDailyVideo, hourlyInitialDelay, 60 * 60, TimeUnit.SECONDS);

        // 每天00:00:01任务
        long dailyInitialDelay = calculateInitialDelay(LocalTime.now(), LocalTime.of(0, 0, 1));
        dailyScheduler.scheduleAtFixedRate(clearTempFiles, dailyInitialDelay, 24 * 60 * 60, TimeUnit.SECONDS);

        // 每天01:00:01任务
        long commonInitialDelay = calculateInitialDelay(LocalTime.now(), LocalTime.of(1, 0, 1));
        constellationScheduler.scheduleAtFixedRate(getConstellationList, commonInitialDelay, 24 * 60 * 60, TimeUnit.SECONDS);
        addOldCalendarScheduler.scheduleAtFixedRate(addOldCalendar, commonInitialDelay, 24 * 60 * 60, TimeUnit.SECONDS);

        // 每天22:00:01任务
        long sendLunarEmailDelay = calculateInitialDelay(LocalTime.now(), LocalTime.of(22, 0, 1));
        sendLunarEmailDelayScheduler.scheduleAtFixedRate(createSendLunarEmail(), sendLunarEmailDelay, 24 * 60 * 60, TimeUnit.SECONDS);

        // 每天6:00:01任务
        long sendConstellationEmailDelay = calculateInitialDelay(LocalTime.now(), LocalTime.of(6, 0, 1));
        sendConstellationEmailDelayScheduler.scheduleAtFixedRate(createSendConstellationEmail(), sendConstellationEmailDelay, 24 * 60 * 60, TimeUnit.SECONDS);
    }

    // 计算当前时间到下一个整点的初始延迟
    private long calculateInitialDelayToNextFullHour(LocalTime now) {
        long nowSeconds = now.toSecondOfDay();
        long nextFullHourSeconds = (now.getHour() + 1) * 60 * 60;  // 下一整点的秒数
        return nextFullHourSeconds - nowSeconds;  // 当前时间到下一整点的秒数
    }

    // 关闭所有调度器
    public void shutdownSchedulers() {
        hourlyScheduler.shutdown();
        dailyScheduler.shutdown();
        constellationScheduler.shutdown();
        addOldCalendarScheduler.shutdown();
    }

    private Runnable createSendLunarEmail() {
        return () -> {
            sendGroupEmailOnLunar();
        };
    }



    private Runnable createSendConstellationEmail() {
        return () -> {
            sendGroupEmailOnConstellation();
        };
    }

    // 群发邮件方法
    public void sendGroupEmailOnLunar() {
        // 遍历邮件组，发送邮件给每个成员
        for (Map.Entry<String, Member> entry : emailGroup.entrySet()) {
            Member member = entry.getValue();
            System.out.println("准备发送老黄历邮件给 " + member.getName() + " (" + member.getEmail() + ")");
            emailUtil.sendHtmlEmailOnDisk("qq", member.getEmail(), member.getName() + "，晚上好，" + getTomorrowTime("yyyy年MM月dd日") + "明日老黄历运势请查收", "/project/media/file/html/" + getTomorrowTime(DATE_FORMATTER) + ".html");
        }
    }



    // 群发邮件方法
    public void sendGroupEmailOnConstellation() {
        List<ConstellationDTO> constellationFortune = yunoService.getConstellationFortune();
        // 遍历邮件组，发送邮件给每个成员
        for (Map.Entry<String, Member> entry : emailGroup.entrySet()) {
            Member member = entry.getValue();
            // 使用 Stream API 过滤出 constellation 为成员的星座的元素
            Optional<ConstellationDTO> constellation = constellationFortune.stream()
                    .filter(c -> member.getZodiacSign().equals(c.getConstellation()))
                    .findFirst(); // 找到第一个匹配的元素
            // 打印日志信息（建议使用日志框架）
            System.out.println("准备发送星座邮件给 " + member.getName() + " (" + member.getEmail() + ") ");
            // 检查 Optional 是否有值
            if (constellation.isPresent()) {
                emailUtil.sendGroupEmailOnConstellation(
                        "qq",
                        member.getEmail(),
                        member.getName() + "，早上好," + getTime("yyyy年MM月dd日") + "今日份星座运势请查收",
                        member.getHtmlName(),
                        constellation.get() // 提取值传递给邮件发送方法
                );
            } else {
                System.out.println("没有找到星座数据，无法发送邮件给 " + member.getName());
            }
        }
    }


    // Member 类，用于存储姓名、邮箱和星座信息
    public static class Member {
        private String name;
        private String email;
        private String zodiacSign;
        private String htmlName;

        public String getName() {
            return name;
        }

        public String getEmail() {
            return email;
        }

        public String getZodiacSign() {
            return zodiacSign;
        }

        public String getHtmlName() {
            return htmlName;
        }

        public Member(String name, String email, String zodiacSign, String htmlName) {
            this.name = name;
            this.email = email;
            this.zodiacSign = zodiacSign;
            this.htmlName = htmlName;
        }

    }
}
